﻿using System;
using System.Collections.Specialized;
using System.IO;

namespace Microsoft.WowAddonStudio.Project.Import
{
	/// <summary>
	/// Path-related functions for copy.
	/// </summary>
	internal static class PathUtils
	{
		/// <summary>
		/// Calculates the relative path from fromPath to toPath.
		/// </summary>
		/// <param name="fromPath">Source directory or file.</param>
		/// <param name="toPath">Target directory or file.</param>
		/// <returns>Relative path between the two paths.</returns>
		internal static string RelativePathTo(string fromPath, string toPath)
		{
			if (fromPath == null)
				throw new ArgumentNullException("fromPath");

			if (toPath == null)
				throw new ArgumentNullException("toPath");

			bool isRooted = Path.IsPathRooted(fromPath) && Path.IsPathRooted(toPath);

			if (isRooted)
			{
				bool isDifferentRoot = string.Compare(
				                       	Path.GetPathRoot(fromPath),
				                       	Path.GetPathRoot(toPath), true) != 0;

				if (isDifferentRoot)
					return toPath;
			}

			var relativePath = new StringCollection();
			string[] fromDirectories = fromPath.Split(
				Path.DirectorySeparatorChar);

			string[] toDirectories = toPath.Split(
				Path.DirectorySeparatorChar);

			int length = Math.Min(
				fromDirectories.Length,
				toDirectories.Length);

			int lastCommonRoot = -1;

			// find common root
			for (int x = 0; x < length; x++)
			{
				if (string.Compare(fromDirectories[x],
				                   toDirectories[x], true) != 0)
					break;

				lastCommonRoot = x;
			}

			if (lastCommonRoot == -1)
				return toPath;

			// add relative folders in from path
			for (int x = lastCommonRoot + 1; x < fromDirectories.Length; x++)
				if (fromDirectories[x].Length > 0)
					relativePath.Add("..");

			// add to folders to path
			for (int x = lastCommonRoot + 1; x < toDirectories.Length; x++)
				relativePath.Add(toDirectories[x]);

			// create relative path
			var relativeParts = new string[relativePath.Count];
			relativePath.CopyTo(relativeParts, 0);

			string newPath = string.Join(
				Path.DirectorySeparatorChar.ToString(),
				relativeParts);

			return newPath;
		}
	}
}